#include <QDir>
#include <QApplication>
#include <QDebug>

#include "defines.h"
#include "directoryutilities.h"
#include "generatoroutputview.h"

DirectoryUtilities::DirectoryUtilities(GeneratorOutputView &outputView, GeneratorData &generatorData)
	: m_outputView(outputView),
	m_generatorData(generatorData)
{
}

void DirectoryUtilities::getFiles(const QString &directory, QDir::Filters &filters, const QStringList &nameFilters, int pathLengthToSubstract, const QString &filePrefixToAdd, QStringList &foundFiles)
{
	QDir dir(directory);
	dir.setFilter(filters);
	dir.setNameFilters(nameFilters);
	
	foreach (QFileInfo entry, dir.entryInfoList())
	{
		if (entry.isDir())
		{
			getFiles(entry.canonicalFilePath(), filters, nameFilters, pathLengthToSubstract, filePrefixToAdd, foundFiles);
		}
		else
		{
			QString fileName = entry.absoluteFilePath().mid(pathLengthToSubstract);
			qDebug() << filePrefixToAdd << ", " << fileName;
			foundFiles.append(filePrefixToAdd + fileName);
			m_outputView.printOutput("Widget file: " + filePrefixToAdd + fileName);
		}
	}
}

bool DirectoryUtilities::getFile(const QString &directory, QDir::Filters &filters, const QStringList &nameFilters, QString &foundFile)
{
    QStringList files;
    getFiles(directory, filters, nameFilters, directory.length(), directory, files);

    if(files.count() == 0)
        return false;

    foundFile = files.at(0);

    return true;
}

void DirectoryUtilities::getDirs(const QString &directory, QDir::Filters &filters, const QStringList &nameFilters, int pathLengthToSubstract, const QString &filePrefixToAdd, QStringList &foundDirs)
{
    QDir dir(directory);
    dir.setFilter(filters);
    dir.setNameFilters(nameFilters);

    foreach(QFileInfo entry, dir.entryInfoList()) {
        if(entry.isDir()) {
            foundDirs.append(filePrefixToAdd + entry.baseName());
			getFiles(entry.canonicalFilePath(), filters, nameFilters, pathLengthToSubstract, filePrefixToAdd, foundDirs);
        }
    }
}

void DirectoryUtilities::cleanDirectory(const QString &directory, bool cleanSubdir, const QString &rootDirectory)
{
    QDir dir(directory);
    dir.setFilter(QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot);

    foreach(QFileInfo entry, dir.entryInfoList()) {
        if(entry.isDir()) {
            if(cleanSubdir)
                cleanDirectory(entry.absoluteFilePath(), cleanSubdir, rootDirectory);
            else
                continue;
        }
        else {
            dir.remove(entry.absoluteFilePath());
        }
    }
    if(rootDirectory != directory)
        dir.rmdir(directory);
}

bool DirectoryUtilities::getSubdirectory(const QString &directory, QString &subdir)
{
    bool retval = false;
    QDir dir(directory);
    dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);

    foreach(QFileInfo entry, dir.entryInfoList()) {
        if(entry.isDir()) {
            subdir = entry.absoluteFilePath();
            retval = true;
            break;
        }
    }


    return retval;
}


bool DirectoryUtilities::copyDirectory(const QString &srcDirectory, const QString &destDirectory, bool deleteOriginal/*= false*/)
{
    QDir dir(srcDirectory);
    dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);

    foreach(QFileInfo entry, dir.entryInfoList()) {
            if(entry.isDir()) {
                QString destSubdir(entry.absoluteFilePath());
                destSubdir.replace(srcDirectory, "");
                copyDirectory(entry.absoluteFilePath(), destDirectory + destSubdir);
                if(deleteOriginal) {
                    cleanDirectory(entry.absoluteFilePath(), true, srcDirectory);
                }
            }
            else {
                QString destDir(destDirectory+"/");
                QFile srcFile(entry.absoluteFilePath());
                if(!srcFile.open(QIODevice::ReadOnly)) {
                    QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(entry.absoluteFilePath());
                    m_outputView.printOutput(errMsg);
                    return false;
                }
                QString destFilename(destDirectory+"/"+entry.fileName());
                if(srcFile.exists(destFilename))
                    srcFile.remove(destFilename);
                else if(!srcFile.exists(destDirectory)) {
                    QDir destDir;
                    destDir.mkpath(destDirectory);
                }

                if(!srcFile.copy(destFilename)) {
                    QString errMsg = QString(ERR_FILE_COPY_FAILED).arg(entry.absoluteFilePath()).arg(destFilename);
                    m_outputView.printOutput(errMsg);
                    return false;
                }

                if(deleteOriginal) {
                    srcFile.remove(entry.absoluteFilePath());
                }
            }
    }

    return true;
}
